package com.ybear.ybutils.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Html;
import android.text.Spanned;
import android.util.DisplayMetrics;

import androidx.annotation.AnimatorRes;
import androidx.annotation.ArrayRes;
import androidx.annotation.BoolRes;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.FontRes;
import androidx.annotation.IntegerRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.annotation.XmlRes;

import java.lang.reflect.Field;

public class ResUtil {
    /**
     * 支持显示图片的fromHtml
     *
     * <code>"<img src='ic_test_icon'/>"</code>
     * ic_test_icon为图片资源，即：R.drawable.ic_test_icon
     * @param context       上下文
     * @param content       文本
     * @param cls           <code>R.drawable.class</code>
     * @param resName       资源名称。eg：ic_test_icon
     * @return              结果
     */
    public static Spanned fromHtmlOfResImg(@NonNull Context context,
                                           @NonNull String content,
                                           @NonNull Class<?> cls,
                                           @Nullable String... resName) {
        if( resName != null && resName.length > 0 ) {
            StringBuilder resStr = new StringBuilder();
            for( String s : resName ) resStr.append( "<img src='" ).append( s ).append( "'/>" );
            content = String.format( content, resStr.toString() );
        }
        return Html.fromHtml(content, (source) -> {
            try {
                //检查是否为传入的类
                if ( cls.getField( source ).get( null ) == null ) return null;
                Drawable d = ResUtil.getDrawable( context, source );
                if( d == null ) return null;
                d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight() );
                return d;
            } catch (Exception e) { return null; }
        }, null);
    }

    /**
     * 支持显示图片的fromHtml
     * * 因为R文件的问题，容易不显示
     *
     * <code>"<img src='ic_icon'/>"</code>
     * ic_icon为图片资源，即：R.drawable.ic_icon
     * @param context       上下文
     * @param content       文本
     * @param resName       资源名称。eg：ic_test_icon
     * @return              结果
     */
    @Deprecated
    public static Spanned fromHtmlOfResImg(@NonNull Context context,
                                           @NonNull String content,
                                           @Nullable String[] resName) {
        return fromHtmlOfResImg( context, content, R.drawable.class, resName );
    }

    public static int getIdentifier(@NonNull Context context, String name, String type) {
        try {
            return context.getResources().getIdentifier( name, type, context.getPackageName() );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int getLayoutId(@NonNull Context context, @NonNull String name) {
        return getIdentifier( context, name, "layout" );
    }

    public static int getDrawableId(@NonNull Context context, @NonNull String name) {
        return getIdentifier( context, name, "drawable" );
    }

    public static String getString(@NonNull Context context, @StringRes int resId) {
        try {
            return context.getResources().getString( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getString(@NonNull Context context,
                                   @StringRes int resId, Object... formatArgs) {
        try {
            return context.getResources().getString( resId, formatArgs );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getString(@NonNull Context context, @NonNull String name) {
        return getString( context, getIdentifier( context, name, "string" ) );
    }

    public static CharSequence getText(@NonNull Context context, @StringRes int resId) {
        try {
            return context.getResources().getText( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static CharSequence getText(@NonNull Context context, @StringRes int resId, CharSequence def) {
        try {
            return context.getResources().getText( resId, def );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static CharSequence getText(@NonNull Context context, @NonNull String name) {
        return getText( context, getIdentifier( context, name, "text" ) );
    }

    public static CharSequence[] getTextArray(@NonNull Context context, @ArrayRes int resId) {
        try {
            return context.getResources().getTextArray( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static CharSequence[] getTextArray(@NonNull Context context, @ArrayRes int resId,
                                              @NonNull CharSequence[] def) {
        try {
            return getTextArray( context, resId );
        }catch (Resources.NotFoundException e) {
            e.printStackTrace();
        }
        return def;
    }

    public static CharSequence[] getTextArray(@NonNull Context context, @NonNull String name) {
        return getTextArray( context, getIdentifier( context, name, "textArray" ) );
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    public static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId,
                                       @Nullable Resources.Theme t) {
        try {
            Resources res = context.getResources();
            if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {
                return res.getDrawable( resId, t );
            } else {
                return res.getDrawable( resId );
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    public static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId) {
        return getDrawable( context, resId, null );
    }

    public static Drawable getDrawable(@NonNull Context context, @NonNull String name) {
        return getDrawable( context, getDrawableId( context, name ) );
    }

    @ColorInt
    public static int getColor(@NonNull Context context, @ColorRes int resId) {
        return getColor( context, resId, null );
    }

    @ColorInt
    public static int getColor(@NonNull Context context, @ColorRes int resId,
                               @Nullable Resources.Theme t) {
        try {
            Resources res = context.getResources();
            if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
                return res.getColor( resId, t );
            }else {
                return res.getColor( resId );
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int getColor(@NonNull Context context, @NonNull String name) {
        return getColor( context, getIdentifier( context, name, "color" ) );
    }

    public static ColorStateList getColorStateList(@NonNull Context context, @ColorRes int resId) {
        return getColorStateList( context, resId, null );
    }

    @SuppressLint("UseCompatLoadingForColorStateLists")
    public static ColorStateList getColorStateList(@NonNull Context context, @ColorRes int resId,
                                                   @Nullable Resources.Theme t) {
        try {
            Resources res = context.getResources();
            if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
                return res.getColorStateList( resId, t );
            }else {
                return res.getColorStateList( resId );
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Px
    public static long getDimension(@NonNull Context context, @DimenRes int resId) {
        try {
            return (long) context.getResources().getDimension( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0L;
    }

    @Px
    public static long getDimensionPixelOffset(@NonNull Context context, @DimenRes int resId) {
        try {
            return context.getResources().getDimensionPixelOffset( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0L;
    }

    @Px
    public static long getDimensionPixelSize(@NonNull Context context, @DimenRes int resId) {
        try {
            return context.getResources().getDimensionPixelSize( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0L;
    }

    public static boolean getBool(@NonNull Context context, @BoolRes int resId) {
        try {
            return context.getResources().getBoolean( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public static float getFloat(@NonNull Context context, @DimenRes int resId) {
        try {
            return context.getResources().getFloat( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0F;
    }

    public static int getInt(@NonNull Context context, @IntegerRes int resId) {
        try {
            return context.getResources().getInteger( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int[] getIntArray(@NonNull Context context, @ArrayRes int resId) {
        try {
            return context.getResources().getIntArray( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    public static Typeface getFont(@NonNull Context context, @FontRes int resId) {
        try {
            return context.getResources().getFont( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static XmlResourceParser getLayout(@NonNull Context context, @LayoutRes int resId) {
        try {
            return context.getResources().getLayout( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static XmlResourceParser getAnim(@NonNull Context context, @AnimatorRes int resId) {
        try {
            return context.getResources().getAnimation( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static XmlResourceParser getXml(@NonNull Context context, @XmlRes int resId) {
        try {
            return context.getResources().getXml( resId );
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static AssetManager getXml(@NonNull Context context) {
        try {
            return context.getResources().getAssets();
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static DisplayMetrics getDisplayMetrics(@NonNull Context context) {
        try {
            return context.getResources().getDisplayMetrics();
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
